package cn.lijiajia3515.starter.web.autoconfigure.exception;

import cn.lijiajia3515.cairo.core.business.DefaultBusiness;
import cn.lijiajia3515.cairo.core.exception.BusinessException;
import cn.lijiajia3515.cairo.core.result.error.ErrorBusinessResult;
import cn.lijiajia3515.cairo.core.util.ThrowableUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Slf4j(topic = "[RestExceptionHandler]")
@RestControllerAdvice(annotations = RestController.class)
@Configuration(proxyBeanMethods = false)
@Order(100)
public class CairoExceptionRestHandlerAutoConfiguration {

	@ExceptionHandler(BusinessException.class)
	public ResponseEntity<ErrorBusinessResult> statusException(BusinessException ex, HttpServletRequest request, HttpServletResponse response) {
		log.debug("[BusinessException] url-> [{}]", request.getRequestURI());
		log.debug("[BusinessException]", ex);
		HttpStatus status = (DefaultBusiness.Success.code.equals(ex.business().code())) ? HttpStatus.OK : HttpStatus.INTERNAL_SERVER_ERROR;
		return ResponseEntity
			.status(status)
			.body(ErrorBusinessResult.builder()
				.business(ex.business())
				.exceptions(ThrowableUtil.extractCause(ex, null))
				.build()
			);
	}

	@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
	public ResponseEntity<ErrorBusinessResult> httpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e, HttpServletRequest request) {
		log.debug("[HttpRequestMethodNotSupportedException] url-> [{}]", request.getRequestURI());
		log.debug("[HttpRequestMethodNotSupportedException]", e);
		return ResponseEntity
			.status(HttpStatus.BAD_REQUEST)
			.body(ErrorBusinessResult.builder()
				.business(DefaultBusiness.Failed)
				.exceptions(ThrowableUtil.extractCause(e, null))
				.build()
			);
	}

	@ExceptionHandler(value = {RuntimeException.class, Exception.class})
	public ResponseEntity<ErrorBusinessResult> runtimeException(RuntimeException e, HttpServletRequest request) {
		log.debug("[Exception] url-> [{}]", request.getRequestURI());
		log.debug("[Exception]", e);
		return ResponseEntity
			.status(HttpStatus.INTERNAL_SERVER_ERROR)
			.body(ErrorBusinessResult.builder()
				.business(DefaultBusiness.Unknown)
				.exceptions(ThrowableUtil.extractCause(e, null))
				.build()
			);
	}

}
